package com.heima.wemedia.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.heima.common.aliyun.GreenImageUploadScan;
import com.heima.common.aliyun.GreenTextScan;
import com.heima.common.aliyun.OSSService;
import com.heima.common.delayTask.RedisDelayedQueueUtil;
import com.heima.common.enums.AppHttpCodeEnum;
import com.heima.common.exception.LeadException;
import com.heima.common.util.BeanHelper;
import com.heima.common.util.SensitiveWordUtil;
import com.heima.feign.ArticleFeignClient;
import com.heima.file.service.MinioService;
import com.heima.model.media.dtos.WmNewsResultDTO;
import com.heima.wemedia.entity.WmNews;
import com.heima.wemedia.entity.WmSensitive;
import com.heima.wemedia.service.WmNewsAuditService;
import com.heima.wemedia.service.WmNewsService;
import com.heima.wemedia.service.WmSensitiveService;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
@Slf4j
public class WmNewsAuditServiceImpl implements WmNewsAuditService {
    /**
     * 自媒体文章审核
     * @param wmNews  自媒体文章
     */

    @Autowired
    private ArticleFeignClient articleFeignClient;

    @Autowired
    private OSSService ossService;

    @Autowired
    private GreenTextScan greenTextScan;

    @Autowired
    private GreenImageUploadScan greenImageUploadScan;

    @Autowired
    private MinioService minioService;

    @Autowired
    private WmNewsService wmNewsService;

    @Async
    @Override
    @GlobalTransactional
    public void auditWmNews(WmNews wmNews) {
        wmNews.setSubmitedTime(new Date());
        String images = wmNews.getImages();
        List<byte[]> bytesList = new ArrayList<>();
        String text = "";
        if (StringUtils.isNotBlank(wmNews.getContent())) {
            String content = wmNews.getContent();
            log.info("content={}", content);
            List<Map<String, Object>> mapList = JSON.parseObject(content, new TypeReference<List<Map<String, Object>>>() {});
            log.info("maplist=====>>{}", mapList.toString());
            if (!CollectionUtils.isEmpty(mapList)) {
                for (Map<String, Object> stringObjectMap : mapList) {
                    String type = stringObjectMap.get("type").toString();
                    if ("text".equals(type)) {
                        text += stringObjectMap.get("value").toString();
                        log.info("一个文本");
                    } else if ("image".equals(type)) {
                        String url = stringObjectMap.get("value").toString();
                        byte[] bytes = minioService.downLoadFile(url);
                        bytesList.add(bytes);
                        log.info("一个图片");
                    }
                }
            }
        }
        Map<String, Integer> matchWords = this.checkWords(text);
        if (!CollectionUtils.isEmpty(matchWords)) {
            wmNews.setStatus(2);
            wmNews.setReason("文本中有敏感词="+matchWords);
            wmNewsService.updateById(wmNews);
            log.info("文本违规");
            return;
        }
        Map<String, String> textResultMap = new HashMap<>();
        Map<String, String> imgResultMap = new HashMap<>();
        if (StringUtils.isNotBlank(text)) {
            try {
                textResultMap = greenTextScan.greenTextScan(text);
            } catch (Exception e) {
                e.printStackTrace();
                throw new LeadException(AppHttpCodeEnum.ALIYUN_TEXT_SCAN_ERROR);
            }
        }
        if (CollectionUtils.isEmpty(textResultMap)) {
            throw new LeadException(AppHttpCodeEnum.ALIYUN_TEXT_SCAN_ERROR);
        }



        String suggestionText = textResultMap.get("suggestion");
        log.info("suggestion=====>>>>>>{}", suggestionText);
        if ("review".equals(suggestionText)) {
            wmNews.setStatus(3);
            wmNews.setReason(textResultMap.get("reason"));
            wmNewsService.updateById(wmNews);
            log.info("文本需要进一步人工审核");
            return;
        } else if ("block".equals(suggestionText)) {
            wmNews.setStatus(2);
            wmNews.setReason(textResultMap.get("reason"));
            wmNewsService.updateById(wmNews);
            log.info("文本违规");
            return;
        } else if ("pass".equals(suggestionText)){
            log.info("文本通过");
        }



        if (StringUtils.isNotBlank(images)){
            String[] split = images.split(",");
            for (String s : split) {
                byte[] bytes = minioService.downLoadFile(s);
                bytesList.add(bytes);
            }
        }


        try {
            imgResultMap = greenImageUploadScan.imageScan(bytesList);
        } catch (Exception e) {
            e.printStackTrace();
            throw new LeadException(AppHttpCodeEnum.ALIYUN_IMG_SCAN_ERROR);
        }
        if (CollectionUtils.isEmpty(imgResultMap)) {
            throw new LeadException(AppHttpCodeEnum.ALIYUN_IMG_SCAN_ERROR);
        }

        String suggestionImg = imgResultMap.get("suggestion");
        log.info("suggestion=====>>>>>>{}", suggestionImg);
        if ("review".equals(suggestionImg)) {
            wmNews.setStatus(3);
            wmNews.setReason(textResultMap.get("reason"));
            wmNewsService.updateById(wmNews);
            log.info("图片需要进一步人工审核");
            return;
        } else if ("block".equals(suggestionImg)) {
            wmNews.setStatus(2);
            wmNews.setReason(textResultMap.get("reason"));
            wmNewsService.updateById(wmNews);
            log.info("图片违规");
            return;
        } else if ("pass".equals(suggestionImg)){
            log.info("图片通过");
        }
        Date publishTime = wmNews.getPublishTime();
        if (publishTime == null) {
            wmNews.setStatus(9);
            wmNews.setPublishTime(new Date());
            wmNews.setReason(textResultMap.get("reason"));
            WmNewsResultDTO wmNewsResultDTO = BeanHelper.copyProperties(wmNews, WmNewsResultDTO.class);
            Long articleId = articleFeignClient.save(wmNewsResultDTO);
            wmNews.setArticleId(articleId);
            wmNewsService.updateById(wmNews);
        } else {
            boolean before = publishTime.before(new Date());
            if (before) {
                wmNews.setStatus(9);
                wmNews.setReason(textResultMap.get("reason"));
                WmNewsResultDTO wmNewsResultDTO = BeanHelper.copyProperties(wmNews, WmNewsResultDTO.class);
                Long articleId = articleFeignClient.save(wmNewsResultDTO);
                wmNews.setArticleId(articleId);
                wmNewsService.updateById(wmNews);
            } else {
                wmNews.setStatus(8);
                wmNews.setReason(textResultMap.get("reason"));
                wmNewsService.updateById(wmNews);
                long delayTime = publishTime.getTime() - System.currentTimeMillis();
                delayedQueueUtil.addQueue(wmNews, delayTime, TimeUnit.MILLISECONDS, "wm.news.pub");
            }
        }

    }

    @Autowired
    private RedisDelayedQueueUtil delayedQueueUtil;
    @Autowired
    private WmSensitiveService wmSensitiveService;

    public Map<String, Integer> checkWords(String text){
        log.info("开始敏感词检测");
        List<WmSensitive> wmSensitives = wmSensitiveService.list();
        List<String> collect = wmSensitives.stream().map(WmSensitive::getSensitives).collect(Collectors.toList());
        Map<String, Integer> matchWords = SensitiveWordUtil.matchWords(collect, text);
        log.info("敏感词匹配结果={}",matchWords.toString());
        return matchWords;
    }

}
